﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;//
using Tank.Properties;//
using System.Threading;//
using System.Windows.Forms;//

namespace Tank
{
    /// <summary>
    /// 游戏管理类
    /// </summary>
    public class GameMana
    {
        #region 各类游戏元素
        /// <summary>
        /// 障碍物——砖块（集合）
        /// </summary>
        private List<Brick> bricks = new List<Brick>();

        /// <summary>
        /// 障碍物——石块（集合）
        /// </summary>
        private List<Stone> stones = new List<Stone>();

        /// <summary>
        /// 玩家子弹集合
        /// </summary>
        private List<PlayerShell> PShells = new List<PlayerShell>();

        /// <summary>
        /// 敌方坦克集合
        /// </summary>
        private List<Enemy> eTanks = new List<Enemy>();

        /// <summary>
        /// 敌方弹药集合
        /// </summary>
        private List<EShell> eShells = new List<EShell>();

        /// <summary>
        /// 爆炸动画集合
        /// </summary>
        private List<Blast> blasts = new List<Blast>();

        /// <summary>
        /// 闪耀登场动画集合
        /// </summary>
        private List<Born> borns = new List<Born>();

        #endregion

        #region 唯一实例
        /// <summary>
        /// 唯一实例
        /// </summary>
        private static volatile GameMana instance;

        /// <summary>
        /// 唯一实例
        /// </summary>
        /// <returns></returns>
        public static GameMana Instance()
        {
            if (instance == null)
                lock (typeof(GameMana))//多线程中共享资源同步
                    if (instance == null)
                        instance = new GameMana();
            return instance;
        }

        protected GameMana()
        {
        }
        #endregion

        #region 游戏管理

        /// <summary>
        /// 初始化游戏地图
        /// </summary>
        /// <param name="map"></param>
        /// <param name="g"></param>
        public void InitGameMap(Graphics g)
        {
            Rness = new Random();
            EMax = 20;
            Existing = EMax;
            Map = GameMap.GetGameMap(Level);

            for (int x = 0; x < 13; x++)
                for (int y = 0; y < 10; y++)
                {
                    if (Map[x, y] == 1) //此处为砖块
                    {
                        AddGameElement(new Brick(60 * x, 60 * y));
                        continue;
                    }

                    if (Map[x, y] == 2) //此处为石块
                    {
                        AddGameElement(new Stone(60 * x, 60 * y));
                        continue;
                    }

                    if (Map[x, y] == 3) //此处为草块
                    {
                        Img = Resources.绿草;
                        g.DrawImage(Img, Img.Width * x, Img.Height * y);
                        continue;
                    }

                    if (Map[x, y] == 4) //此处为钢块
                    {
                        Img = Resources.钢块;
                        g.DrawImage(Img, Img.Width * x, Img.Height * y);
                        continue;
                    }
                    /* ^^^^^^^^^ */
                }
        }

        /// <summary>
        /// 初始化玩家
        /// </summary>
        /// <returns></returns>
        public P1Tank InitPlayer()
        {
            p1Tank = new P1Tank(240, 540, 3, 20, Direction.U);
            return p1Tank;
        }

        /// <summary>
        /// 初始化敌方参战坦克
        /// </summary>
        public void InitETanke()
        {
            GameMana.Instance().AddGameElement(new Enemy(120, 0, 2, Direction.D));
            GameMana.Instance().AddGameElement(new Enemy(360, 0, 1, Direction.D));
            GameMana.Instance().AddGameElement(new Enemy(600, 0, 2, Direction.D));
            GameMana.Instance().AddGameElement(new Enemy(0, 180, 3, Direction.D));
            GameMana.Instance().AddGameElement(new Enemy(720, 180, 3, Direction.D));
        }

        #region 添加游戏元素

        /// <summary>
        /// 添加游戏元素
        /// </summary>
        /// <param name="e"></param>
        public void AddGameElement(GameElement e)
        {
            if (e is Brick)//游戏元素为:砖块
            {
                bricks.Add(e as Brick);
                return;
            }

            if (e is Stone)//游戏元素为:石块
            {
                stones.Add(e as Stone);
                return;
            }

            if (e is PlayerShell)//游戏元素为:玩家弹药
            {
                PShells.Add(e as PlayerShell);
                return;
            }

            if (e is Enemy)//游戏元素为:敌方坦克
            {
                eTanks.Add(e as Enemy);
                Existing--; //未参战坦克-1
                EGoToWar++;//参战坦克数量+1
                return;
            }

            if (e is EShell)//游戏元素为:敌方子弹
            {
                eShells.Add(e as EShell);
                return;
            }

            if (e is Born)//游戏元素为:闪耀登场动画
            {
                borns.Add(e as Born);
                return;
            }

            if (e is Blast)//游戏元素为:爆炸动画
            {
                blasts.Add(e as Blast);
                return;
            }
        }

        #endregion

        #region 删除游戏元素
        /// <summary>
        /// 删除游戏元素
        /// </summary>
        /// <param name="e"></param>
        public void DelGameElement(GameElement e)
        {
            if (e is Enemy)//游戏元素为:敌方坦克
            {
                eTanks.Remove(e as Enemy);
                EGoToWar--;//参战敌方坦克-1
                return;
            }

            if (e is PlayerShell)//游戏元素为:玩家弹药
            {
                PShells.Remove(e as PlayerShell);
                return;
            }

            if (e is EShell)//游戏元素为:敌方弹药
            {
                eShells.Remove(e as EShell);
                return;
            }

            if (e is Brick)//游戏元素为:墙砖
            {
                bricks.Remove(e as Brick);
                return;
            }

            if (e is Stone)//游戏元素为:石块
            {
                stones.Remove(e as Stone);
                return;
            }

            if (e is Born)//游戏元素为:闪耀登场动画
            {
                borns.Remove(e as Born);
                return;
            }

            if (e is Blast)//游戏元素为:爆炸动画
            {
                blasts.Remove(e as Blast);
                return;
            }
        }
        #endregion

        #region 设置敌方坦克参战
        /// <summary>
        /// 敌方坦克参战
        /// </summary>
        public void SetEGoToWar()
        {

            if (Existing > 0 && EGoToWar < 5)
            {
                switch (Rness.Next(0, 5))
                {
                    case 0:
                        GameMana.Instance().AddGameElement(new Enemy(120, 0, Rness.Next(1, 4), Direction.D));
                        break;
                    case 1:
                        GameMana.Instance().AddGameElement(new Enemy(360, 0, Rness.Next(1, 4), Direction.D));
                        break;
                    case 2:
                        GameMana.Instance().AddGameElement(new Enemy(600, 0, Rness.Next(1, 4), Direction.D));
                        break;
                    case 3:
                        GameMana.Instance().AddGameElement(new Enemy(0, 180, Rness.Next(1, 4), Direction.D));
                        break;
                    case 4:
                        GameMana.Instance().AddGameElement(new Enemy(720, 180, Rness.Next(1, 4), Direction.D));
                        break;
                }
            }
        }
        #endregion/* 设置敌方坦克参战 */

        #region 画出游戏元素
        /// <summary>
        /// 画出游戏元素
        /// </summary>
        /// <param name="g"></param>
        public void DrawGameeElement(Graphics g)
        {
            p1Tank.Draw(g);

            for (int i = 0; i < bricks.Count; i++)
            {
                bricks[i].Draw(g);  /* 画墙砖 */
            }

            for (int i = 0; i < stones.Count; i++)
            {
                stones[i].Draw(g);  /* 画石块*/
            }

            for (int i = 0; i < PShells.Count; i++)
            {
                PShells[i].Draw(g);  /* 画玩家子弹 */
            }

            for (int i = 0; i < eTanks.Count; i++)
            {
                eTanks[i].Draw(g);  /* 画敌方坦克 */
            }

            for (int i = 0; i < eShells.Count; i++)
            {
                eShells[i].Draw(g);  /* 画敌方子弹 */
            }

            for (int i = 0; i < blasts.Count; i++)  /* 爆炸动画 */
            {
                blasts[i].Draw(g);
            }

            for (int i = 0; i < borns.Count; i++)  /* 闪耀登场 */
            {
                borns[i].Draw(g);
            }
        }
        #endregion

        #region 玩家移动检测
        public void Play(KeyEventArgs e)
        {
            int x = p1Tank.X, y = p1Tank.Y; //移动前的坐标

            p1Tank.KeyDonw(e);//移动

            for (int i = 0; i < eTanks.Count; i++)
            {
                if (p1Tank.GetRectangle().IntersectsWith(eTanks[i].GetRectangle())) // 发生碰撞
                {
                    /* 坐标复原 */
                    p1Tank.X = x;        
                    p1Tank.Y = y;
                }
            }

        }
        #endregion
       

        /// <summary>
        /// 使用多线程
        /// </summary>
        public void CreateThread()
        {
            Thread hitThread = new Thread(new ThreadStart(MeetDetection));
            hitThread.Start();//开启多线程
        }

        #region 游戏元素相遇检测
        /// <summary>
        /// 游戏元素相遇检测
        /// </summary>
        public void MeetDetection()
        {
            #region 玩家坦克是否与障碍物相遇

            for (int i = 0; i < bricks.Count; i++) /* 玩家坦克是否和砖块相遇 */
            {
                if (p1Tank.GetRectangle().IntersectsWith(bricks[i].GetRectangle()))
                {
                    switch (p1Tank.Dir)
                    {
                        case Direction.U:
                            p1Tank.Y = bricks[i].Y + bricks[i].Height;
                            break;
                        case Direction.D:
                            p1Tank.Y = bricks[i].Y - bricks[i].Height;
                            break;
                        case Direction.L:
                            p1Tank.X = bricks[i].X + bricks[i].Width;
                            break;
                        case Direction.R:
                            p1Tank.X = bricks[i].X - bricks[i].Width;
                            break;
                    }
                }

            }

            for (int i = 0; i < stones.Count; i++) /* 玩家坦克是否和石块相遇 */
            {
                if (p1Tank.GetRectangle().IntersectsWith(stones[i].GetRectangle()))
                {
                    switch (p1Tank.Dir)
                    {
                        case Direction.U:
                            p1Tank.Y = stones[i].Y + stones[i].Height;
                            break;
                        case Direction.D:
                            p1Tank.Y = stones[i].Y - stones[i].Height;
                            break;
                        case Direction.L:
                            p1Tank.X = stones[i].X + stones[i].Width;
                            break;
                        case Direction.R:
                            p1Tank.X = stones[i].X - stones[i].Width;
                            break;
                    }
                }
            }

            #endregion
            #region 玩家子弹与游戏元素相遇
            #region 超出边界
            for (int i = 0; i < PShells.Count; i++)
            {
                if (PShells[i].Life == 0)
                {
                    PShells.Remove(PShells[i]);//删除之
                    break;
                }
            }
            #endregion
            #region 与砖块相遇
            for (int i = 0; i < PShells.Count; i++)
            {
                for (int k = 0; k < bricks.Count; k++)
                {
                    if (PShells[i].GetRectangle().IntersectsWith(bricks[k].GetRectangle()))
                    {
                        Sound.Play(@"Sound\fire.wav");
                        DelGameElement(PShells[i]);
                        DelGameElement(bricks[k]);
                        break;
                    }
                }
            }
            #endregion
            #region 与石块相遇
            for (int i = 0; i < PShells.Count; i++)
            {
                for (int k = 0; k < stones.Count; k++)
                {
                    if (PShells[i].GetRectangle().IntersectsWith(stones[k].GetRectangle()))
                    {
                        Sound.Play(@"Sound\hit.wav");
                        PShells.Remove(PShells[i]);
                        break;
                    }
                }
            }
            #endregion
            #region 与敌方坦克相遇
            for (int i = 0; i < PShells.Count; i++)
            {
                for (int k = 0; k < eTanks.Count; k++)
                {
                    if (PShells[i].GetRectangle().IntersectsWith(eTanks[k].GetRectangle()))
                    {
                        Sound.Play(@"Sound\fire.wav");
                        if (eTanks[k].HurtClac(p1Tank) <= 0)
                        {
                            eTanks[k].Life = -1;
                        }
                        PShells.Remove(PShells[i]);
                        break;
                    }
                }
            }
            #endregion
            #region 消除无影弹
            for (int i = 1; i < PShells.Count; i++)
            {
                if (PShells[i].GetRectangle().IntersectsWith(PShells[i - 1].GetRectangle()))
                {
                    PShells.Remove(PShells[i]);
                    break;
                }
            }
            #endregion
            #endregion

            #region 敌方坦克是否与障碍物相遇
            for (int i = 0; i < eTanks.Count; i++)//和砖墙相遇
            {
                for (int k = 0; k < bricks.Count; k++)
                {
                    if (eTanks[i].GetRectangle().IntersectsWith(bricks[k].GetRectangle()))
                    {
                        eTanks[i].IsSuffocate = true;

                        switch (eTanks[i].Dir)
                        {
                            case Direction.U:
                                eTanks[i].Y = bricks[k].Y + bricks[k].Height;
                                break;
                            case Direction.D:
                                eTanks[i].Y = bricks[k].Y - bricks[k].Height;
                                break;
                            case Direction.L:
                                eTanks[i].X = bricks[k].X + bricks[k].Width;
                                break;
                            case Direction.R:
                                eTanks[i].X = bricks[k].X - bricks[k].Width;
                                break;
                        }
                        if (Rness.Next(100) < 5)
                        {
                            AddGameElement(new EShell(eTanks[i], 1, 5, 1));
                        }
                    }
                }
            }

            for (int i = 0; i < eTanks.Count; i++)//和石块相遇
            {
                for (int k = 0; k < stones.Count; k++)
                {
                    if (eTanks[i].GetRectangle().IntersectsWith(stones[k].GetRectangle()))
                    {
                        eTanks[i].IsSuffocate = true;

                        switch (eTanks[i].Dir)
                        {
                            case Direction.U:
                                eTanks[i].Y = stones[k].Y + stones[k].Height;
                                break;
                            case Direction.D:
                                eTanks[i].Y = stones[k].Y - stones[k].Height;
                                break;
                            case Direction.L:
                                eTanks[i].X = stones[k].X + stones[k].Width;
                                break;
                            case Direction.R:
                                eTanks[i].X = stones[k].X - stones[k].Width;
                                break;
                        }
                        if (Rness.Next(100) < 5)
                        {
                            AddGameElement(new EShell(eTanks[i], 1, 5, 1));
                        }
                    }
                }
            }

            for (int i = 0; i < eTanks.Count; i++) /* 和玩家坦克相遇 */
            {
                if (eTanks[i].GetRectangle().IntersectsWith(p1Tank.GetRectangle()))
                {
                    eTanks[i].IsSuffocate = true;

                    int x = p1Tank.X;
                    int y = p1Tank.Y;

                    switch (eTanks[i].Dir)
                    {
                        case Direction.U:
                            eTanks[i].Y = y + 60;
                            break;
                        case Direction.D:
                            eTanks[i].Y = y - 60;
                            break;
                        case Direction.L:
                            eTanks[i].X = x + 60;
                            break;
                        case Direction.R:
                            eTanks[i].X = x - 60;
                            break;
                    }
                    if (Rness.Next(100) < 5)
                    {
                      //  AddGameElement(new EShell(eTanks[i], 1, 5, 1));
                    }

                }
            }
            #endregion
            #region 敌方子弹是否与障碍物相遇

            for (int i = 0; i < eShells.Count; i++)//超出游戏界面删除之
            {
                if (eShells[i].Life == 0)
                {
                    eShells.Remove(eShells[i]);
                    break;
                }
            }
            for (int i = 0; i < eShells.Count; i++)//子弹与墙砖相遇
            {
                for (int k = 0; k < bricks.Count; k++)
                {
                    if (eShells[i].GetRectangle().IntersectsWith(bricks[k].GetRectangle()))
                    {
                        Sound.Play(@"Sound\fire.wav");
                        eShells.Remove(eShells[i]);
                        bricks.Remove(bricks[k]);
                        break;
                    }
                }
            }

            for (int i = 0; i < eShells.Count; i++)//子弹与石块相遇
            {
                for (int k = 0; k < stones.Count; k++)
                {
                    if (eShells[i].GetRectangle().IntersectsWith(stones[k].GetRectangle()))
                    {
                        Sound.Play(@"Sound\hit.wav");
                        eShells.Remove(eShells[i]);
                        break;
                    }
                }
            }

            for (int i = 0; i < eShells.Count; i++)//子弹与玩家相遇
            {
                if (eShells[i].GetRectangle().IntersectsWith(p1Tank.GetRectangle()))
                {
                    Sound.Play(@"Sound\fire.wav");
  
                    if (p1Tank.HurtClac(eShells[i].Master) <= 0) 
                    {
                        p1Tank.Life -= 1;
                    } 
                    eShells.Remove(eShells[i]);
                    break;
                }
            }
        }

            #endregion
        #endregion
        #endregion/* 游戏管理end */

        #region 游戏元素属性

        /// <summary>
        /// 玩家1
        /// </summary>
        public P1Tank p1Tank { get; set; }

        /// <summary>
        /// 玩家2
        /// </summary>
        public P1Tank p2Tank { get; set; }

        /// <summary>
        /// 游戏关卡
        /// </summary>
        public static GameLevel Level { get; set; }

        /// <summary>
        /// 游戏地图
        /// </summary>
        public static int[,] Map { get; set; }

        /// <summary>
        /// 游戏元素图片
        /// </summary>
        public static Image Img { get; set; }

        /// <summary>
        /// 敌方坦克上限
        /// </summary>
        public int EMax { get; set; }

        /// <summary>
        /// 敌方参战坦克数量
        /// </summary>
        public int EGoToWar { get; set; }

        /// <summary>
        ///  敌方未参战坦克数
        /// </summary>
        public int Existing { get; set; }

        /// <summary>
        /// 人品器
        /// </summary>
        public Random Rness { get; set; }

        #endregion
    }
}